package com.container.bootstrap;

import io.netty.bootstrap.Bootstrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ClassUtils;

import com.container.core.MyServletContainer;
import com.container.core.MyServletContext;

import javax.servlet.ServletException;
import java.net.InetSocketAddress;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Random;

public class MyEmbeddedServletContainerFactory extends AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware {
    private final Logger log = LoggerFactory.getLogger(getClass());//日志
    private static final String serverInfo = "MyNettyContainer";
    private ResourceLoader resourceLoader;

    //spring boot会调用这个方法来获取内嵌容器
    @Override
    public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
        ClassLoader parentClassLoader = resourceLoader != null ? resourceLoader.getClassLoader() : ClassUtils.getDefaultClassLoader();
        
        Package p = Bootstrap.class.getPackage();
        String title = p.getImplementationTitle();
        String version = p.getImplementationVersion();
        log.info("Running with " + title + " " + version);
        if (isRegisterDefaultServlet()) {
            log.warn("no default servlet");//不支持默认servlet
        }

        MyServletContext servletContext = new MyServletContext(getContextPath(), new URLClassLoader(new URL[]{}, parentClassLoader), serverInfo);
        //初始化上下文配置（如果有的话）
        for (ServletContextInitializer initializer : initializers) {
            try {
                initializer.onStartup(servletContext);
            } catch (ServletException e) {
                throw new RuntimeException(e);
            }
        }

        int port = getPort() > 0 ? getPort() : 9000;//默认端口9000
        InetSocketAddress address = new InetSocketAddress(port);
        return new MyServletContainer(address, servletContext);
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}